// React是导出的默认组件,所以不需要加{},而useEffect是单独导出的组件,需要加{}
import React, { useEffect, useState } from 'react';
import { PageContainer } from '@ant-design/pro-layout';
// 引入connect
import { connect } from 'umi';
import type { Dispatch } from 'umi';
import type { MStateType,ArticleType } from './model';
import { Table, Card, Form, Input, Button, Row, Col } from 'antd';
import { pickBy } from 'lodash';
import type { ConnectState } from '@/models/connect.d';
// less文件以模块形式引入 模块名称是styles(引入模块的目的是为了避免全局样式冲突)
import styles  from './index.less';
// 导入子组件
import ArticleEdit from './components/ArticleEdit';
// 引入图标组件 # https://ant.design/components/icon-cn/
import {EditOutlined,DeleteOutlined} from '@ant-design/icons';
// 声明命名空间
const namespace = 'article';
// 声明props类型
type PropsType = {
  articleList: ArticleType[]; 
  dispatch: Dispatch;
  totalCount: number;
  loading: boolean;
};

const ArticleList: React.FC<PropsType> = (props) => {
  // 解构需要用的内容
  const { articleList, totalCount, dispatch, loading } = props;
  // 某个数据是动态的 我们就得使用"响应式＂对象得形式声明,也就是说哪写值变化了,需要更新页面,就需要声明成state
  // 在函数式组件中,因为无法使用this,所以提出来hook形式解决
  // useState 返回了一个数组,第一个参数是变量(响应式对象)名称,第二个是函数名,可以通过第二个函数更新这个变量
  const [pageStart, setPageStart] = useState<number>(1);
  const [pageSize, setPageSize] = useState<number>(10);
  // 定义查询条件
  const [params, setParams] = useState({});
  // 子组件状态提升 modal是否显示交给父组件控制
  const [isModalVisible,setIsModalVisible] = useState(false);
  // 定义editId
  const [editId,setEditId] = useState<string>('');
  // 发送请求 尝试发送请求
  // 声明周期函数
  // componentDidMount(){

  // }
  // useEffect是多个生命周期函数的集合,考虑在这里进行数据初始化/请求
  // useEffect 第一个参数是函数类型,用于触发事件, 第二个参数是依赖于哪写数据的变化才触发
  // 如果只希望在第一次进入的时候触发一次,那么第二个参数为[]数组
  // useEffect   componetDidMount  componentDidUpdate  componentWillUnmount
  useEffect(() => {
    dispatch({
      type: `${namespace}/findArticleList`,
      payload: {
        start: pageStart,
        limit: pageSize,
        params,
      },
    });
  }, [pageStart, pageSize, params]);
  
  // 比葫芦画瓢  找到form组件  定义了form的ref
  const [form] = Form.useForm();
  const onChange = (pageNumber: number, pSize?: number) => {
    // 页面变化的时候触发 需要更改分页变化
    // console.log('Page: ', pageNumber,pSize);
    setPageStart(pageNumber);
    setPageSize(pSize!);
  };
  // 查询的时候触发 如果需要刷新页面,本质需求是改变params对象 触发effect
  const onSearch = (value: { title?: string; author?: string }) => {
    // {author: 'zs', title: undefined} => {author: 'zs'}
    let useParams = { ...value };
    useParams = pickBy(useParams, (item) => item);
    // console.log(useParams);
    setParams({
      ...useParams,
    });
  };
  const resetSearch = () => {
    form.resetFields();
    setParams({});
  };
  // 打开弹窗
  const goAdd = ()=>{
    setEditId('');
    setIsModalVisible(true);
  }
  // 用于刷新数据列表
  const refrushList = ()=>{
    dispatch({
      type: `${namespace}/findArticleList`,
      payload: {
        start: pageStart,
        limit: pageSize,
        params,
      },
    });
  }
  // 去往编辑页
  const goEdit = (id: string)=>{
    // 设置id
    setEditId(id);
    setIsModalVisible(true);
  }
  // 用于控制数据列
  const columns = [
    {
      title: 'id',
      dataIndex: 'id',
      key: 'id',
    },
    {
      title: '标题',
      dataIndex: 'title',
      key: 'title',
    },
    {
      title: '作者',
      dataIndex: 'author',
      key: 'author',
    },
    {
      title: '概要描述',
      dataIndex: 'summary',
      key: 'summary',
    },
    {
      title: '封面图片',
      dataIndex: 'coverImg',
      key: 'coverImg',
      render:(text: string)=> {
      // render:(text: string, record: ArticleType, index: number)=> {
        // console.log('text',text);
        // console.log('record',record);
        // console.log('index',index);
        // 针对className 以及less的使用 随后单独说明
        return (<img className={styles.coverImg} src={text} />);
      }
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'createTime',
    },
    {
      title: '操作',
      key: 'setting',
      render: (text,record: ArticleType)=>{
        return(
          <div>
            <Button title="编辑" onClick={()=>goEdit(record.id!)} type="primary" shape="circle" size="small" icon={<EditOutlined/>}></Button>
            <Button title="删除" style={{marginLeft: 16}}   danger shape="circle" size="small" icon={<DeleteOutlined />}></Button>
          </div>
        )
      }
    },
  ];
  return (
    <PageContainer className={styles.main}>
      <Card title="条件查询" style={{ width: '100%', marginBottom: '30px' }}>
        <Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} onFinish={onSearch} form={form}>
          <Row gutter={32}>
            <Col span={6}>
              <Form.Item label="标题" name="title">
                <Input />
              </Form.Item>
            </Col>
            <Col span={6}>
              <Form.Item label="作者" name="author">
                <Input />
              </Form.Item>
            </Col>
          </Row>
          <Row gutter={32}>
            <Col span={6} offset={18} style={{ textAlign: 'right' }}>
              <Button onClick={resetSearch}>重置</Button>
              {/* htmlType="submit"  把button变成表单默认提交按钮 用于触发onFinish */}
              <Button type="primary" style={{ marginLeft: 30 }} htmlType="submit">
                查询
              </Button>
            </Col>
          </Row>
        </Form>
      </Card>
      <Button onClick={goAdd} type="primary" style={{marginBottom: 30}}>新增</Button>
      <Table
        loading={loading}
        pagination={{
          showQuickJumper: true,
          showSizeChanger: true,
          current: pageStart,
          pageSize,
          total: totalCount,
          onChange,
        }}
        rowKey="id"
        dataSource={articleList}
        columns={columns}
      />
      {/* 子组件 */}
      <ArticleEdit id={editId} refrushList={refrushList} isModalVisible={isModalVisible} setIsModalVisible={setIsModalVisible}/>
    </PageContainer>
  );
};

// 绑定model和组件 把state映射到props
// const mapStateToProps = (state: MStateType)=>({
//   articleList: state[namespace].articleList,
//   totalCount: state[namespace].totalCount,
// })
// 自定义的state不符合,但是可以合并connect.d.ts中的connectState
type StateType = {
  [namespace]: MStateType;
} & ConnectState;
const mapStateToProps = (state: StateType) => {
  console.log('state', state);
  return {
    articleList: state[namespace].articleList,
    totalCount: state[namespace].totalCount,
    loading: state.loading.effects['article/findArticleList'] as boolean,
  };
};
export default connect(mapStateToProps)(ArticleList);
